/**
 * 
 */
package edu.towson.cosc.cosc455.astewart.compiler;

import edu.towson.cosc.cosc455.interfaces.LexicalAnalyzer;

/**
 * @author astewa14
 * a character-by-character lexical analyzer that partitions the lexemes 
 * of a source file in our LOLCODE Markdown language into tokens.
 */
public class MyLexicalAnalyzer implements LexicalAnalyzer { 
	String nextCharacter = "";
	String currentCharacter= "";
	int currentPosition = 0;
	char currentChar; 
	char nextChar;
	
	/* (non-Javadoc)
	 * @see edu.towson.cosc.cosc455.interfaces.LexicalAnalyzer#getNextToken()
	 */
	@Override
	public void getNextToken() {
		// TODO Auto-generated method stub
		//MyCompiler.token;
		getCharacter();
		while (isSpace(currentCharacter)){
			getCharacter();
		}
		if (currentCharacter.equals("#")){
			processTag();
			if(!lookupToken()){
				System.out.println("ERROR! Token " + MyCompiler.token + " is invalid");
				System.exit(0);
			}
		}else if(!currentCharacter.equals("#")){
			processText();
		}
		
	}

	/* (non-Javadoc)
	 * @see edu.towson.cosc.cosc455.interfaces.LexicalAnalyzer#getCharacter()
	 */
	@Override
	public void getCharacter() {
		// TODO Auto-generated method stub
		currentChar=(MyCompiler.completeFile.charAt(currentPosition));
		currentCharacter= currentChar + "";  
		currentPosition++;

	}

	/* (non-Javadoc)
	 * @see edu.towson.cosc.cosc455.interfaces.LexicalAnalyzer#addCharacter()
	 */
	@Override
	public void addCharacter() {
		// TODO Auto-generated method stub
		nextChar=(MyCompiler.completeFile.charAt(currentPosition));
		nextCharacter=nextChar + ""; 
		currentPosition++;
		

	}

	/* (non-Javadoc)
	 * @see edu.towson.cosc.cosc455.interfaces.LexicalAnalyzer#isSpace(java.lang.String)
	 */
	@Override
	public boolean isSpace(String c) {
		if (c.trim().isEmpty()){
			return true;
		}else
			return false;
	}

	/* (non-Javadoc)
	 * @see edu.towson.cosc.cosc455.interfaces.LexicalAnalyzer#lookupToken()
	 */
	@Override
	public boolean lookupToken() {
		// TODO Auto-generated method stub
		if (MyCompiler.legalTokens.contains(MyCompiler.token.toUpperCase())){
			return true;
		}else 
			return false;
	}
	/**
	 * This method handles tokens that are tags.  If the token is not a valid tag, process the next
	 * word in case it is a mutli-word tag.
	 */
	public void processTag(){
		MyCompiler.token = currentCharacter;
		addCharacter();
		while (!isSpace(nextCharacter)){
			MyCompiler.token+=nextCharacter;
			addCharacter();
		}
		if (!lookupToken()){
			processMultiTag();
			if (!lookupToken()){
				processMultiTag();
			}
		}
	}
	/**
	 * This method processes the word following a tag if it is a multi-word tag
	 */
	public void processMultiTag(){
		MyCompiler.token+=nextCharacter;
		addCharacter();
		while (!isSpace(nextCharacter)){
			MyCompiler.token+=nextCharacter;
			addCharacter();
		}
	}
	/**
	 * This method processes text that doesn't include a #
	 */
	public void processText(){
		MyCompiler.token=currentCharacter;
		addCharacter();
		while (!nextCharacter.equals("#")){
			MyCompiler.token+=nextCharacter;
			addCharacter();
		}
		if (nextCharacter.equals("#")){
			currentPosition--;
		}
	}
	
	/**
	 * Checks to see if their are any tokens after #KTHXBYE
	 * @return false if are tokens after #KTHXBYE, else true
	 */
	public boolean isComplete(){
		while (currentPosition<MyCompiler.completeFile.length()){
			addCharacter();
			if (!isSpace(nextCharacter)){
				return false;
			}
			
		} return true;
	}
}
